﻿// <copyright file="BaseSeaUnitImporter.cs" company="Gravity Age Studios">
// Code released under the MIT license (see License.txt).
// </copyright>
// <author>Vicente Cartas Espinel</author>
// <email>vicente.cartas@gmail.com</email>
namespace LightSwitchApplication.Import
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    internal class BaseSeaUnitImporter : VisualCollectionImporter<BaseSeaUnit>
    {
        private readonly int Visibility = 0;
        private readonly int Name = 1;
        private readonly int Type = 2;
        private readonly int Movement = 3;
        private readonly int Melee = 4;
        private readonly int Ram = 5;
        private readonly int Missile = 6;
        private readonly int Defense = 7;
        private readonly int Hits = 8;
        private readonly int Morale = 9;
        private readonly int Seaworthiness = 10;
        private readonly int CargoGBs = 11;
        private readonly int CargoUnits = 12;
        private readonly int Muster = 13;
        private readonly int Maintenance = 14;
        private readonly int Race = 15;
        private readonly int Province = 16;
        private readonly int Law = 17;
        private readonly int Temple = 18;
        private readonly int Guild = 19;
        private readonly int ResearchedBy = 20;
        private readonly int PublicInformation = 21;
        private readonly int OwnerInformation = 22;
        private readonly int GMInformation = 23;

        private IEnumerable<Race> races;
        private IEnumerable<Domain> domains;

        public BaseSeaUnitImporter(DataWorkspace workspace)
            : base(workspace)
        {
        }

        protected override void FetchRequisites()
        {
            this.races = this.workspace.ApplicationData.Races.GetQuery().Execute();
            this.domains = this.workspace.ApplicationData.Domains.GetQuery().Execute();
        }

        protected override bool SkipEntity(int index)
        {
            if (this.headers[Name].HasValue)
            {
                if (this.entities.Any(e => e.Name.Equals(data[index + headers[Name].Value].Trim(), StringComparison.InvariantCultureIgnoreCase) &&
                                           e.Race.Name.Equals(data[index + headers[Race].Value].Trim(), StringComparison.InvariantCultureIgnoreCase)))
                {
                    return true;
                }
            }

            return false;
        }

        protected override int?[] MapHeaders(string[] stringHeaders)
        {
            int?[] headers = new int?[24];

            for (int i = 0; i < stringHeaders.Length; i++)
            {
                if (stringHeaders[i].StartsWith("Vis", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Visibility] = i;
                }
                else if (stringHeaders[i].StartsWith("Nam", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Name] = i;
                }
                else if (stringHeaders[i].StartsWith("Ty", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Type] = i;
                }
                else if (stringHeaders[i].StartsWith("Mov", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Movement] = i;
                }
                else if (stringHeaders[i].StartsWith("Mel", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Melee] = i;
                }
                else if (stringHeaders[i].StartsWith("Ram", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Ram] = i;
                }
                else if (stringHeaders[i].StartsWith("Mis", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Missile] = i;
                }
                else if (stringHeaders[i].StartsWith("Def", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Defense] = i;
                }
                else if (stringHeaders[i].StartsWith("Hit", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Hits] = i;
                }
                else if (stringHeaders[i].StartsWith("Mor", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Morale] = i;
                }
                else if (stringHeaders[i].StartsWith("Sea", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Seaworthiness] = i;
                }
                else if (stringHeaders[i].Contains("GB") || stringHeaders[i].Contains("gb"))
                {
                    headers[CargoGBs] = i;
                }
                else if (stringHeaders[i].Contains("Unit") || stringHeaders[i].Contains("unit"))
                {
                    headers[CargoUnits] = i;
                }
                else if (stringHeaders[i].StartsWith("Mus", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Muster] = i;
                }
                else if (stringHeaders[i].StartsWith("Main", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Maintenance] = i;
                }
                else if (stringHeaders[i].StartsWith("Race", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Race] = i;
                }
                else if (stringHeaders[i].StartsWith("Prov", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Province] = i;
                }
                else if (stringHeaders[i].StartsWith("Law", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Law] = i;
                }
                else if (stringHeaders[i].StartsWith("Temple", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Temple] = i;
                }
                else if (stringHeaders[i].StartsWith("Guild", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Guild] = i;
                }
                else if (stringHeaders[i].StartsWith("Res", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[ResearchedBy] = i;
                }
                else if (stringHeaders[i].StartsWith("Public", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[PublicInformation] = i;
                }
                else if (stringHeaders[i].StartsWith("Owner", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[OwnerInformation] = i;
                }
                else if (stringHeaders[i].StartsWith("GM", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[GMInformation] = i;
                }
            }

            return headers;
        }

        protected override void FillEntity(BaseSeaUnit entity, int index, int?[] headers, string[] data)
        {
            if (headers[Visibility].HasValue)
            {
                int value;
                if (int.TryParse(data[index + headers[Visibility].Value], out value))
                {
                    entity.Visibility = value;
                }
            }

            if (headers[Name].HasValue)
            {
                entity.Name = data[index + headers[Name].Value];
            }

            if (headers[Type].HasValue)
            {
                int value;
                if (int.TryParse(data[index + headers[Type].Value], out value))
                {
                    entity.Type = value;
                }
            }

            if (headers[Movement].HasValue)
            {
                entity.Movement = data[index + headers[Movement].Value];
            }

            if (headers[Melee].HasValue)
            {
                entity.Melee = data[index + headers[Melee].Value];
            }

            if (headers[Ram].HasValue)
            {
                entity.Ram = data[index + headers[Ram].Value];
            }

            if (headers[Missile].HasValue)
            {
                entity.Missile = data[index + headers[Missile].Value];
            }

            if (headers[Defense].HasValue)
            {
                entity.Defense = data[index + headers[Defense].Value];
            }

            if (headers[Hits].HasValue)
            {
                double value;
                if (double.TryParse(data[index + headers[Hits].Value], out value))
                {
                    entity.Hits = value;
                }
            }

            if (headers[Morale].HasValue)
            {
                entity.Morale = data[index + headers[Morale].Value];
            }

            if (headers[Seaworthiness].HasValue)
            {
                double value;
                if (double.TryParse(data[index + headers[Seaworthiness].Value], out value))
                {
                    entity.Seaworthiness = value;
                }
            }

            if (headers[CargoGBs].HasValue)
            {
                double value;
                if (double.TryParse(data[index + headers[CargoGBs].Value], out value))
                {
                    entity.CargoSizeGBs = value;
                }
            }

            if (headers[CargoUnits].HasValue)
            {
                int value;
                if (int.TryParse(data[index + headers[CargoUnits].Value], out value))
                {
                    entity.CargoSizeUnits = value;
                }
            }

            if (headers[Muster].HasValue)
            {
                double value;
                if (double.TryParse(data[index + headers[Muster].Value], out value))
                {
                    entity.MusterCost = value;
                }
            }

            if (headers[Maintenance].HasValue)
            {
                double value;
                if (double.TryParse(data[index + headers[Maintenance].Value], out value))
                {
                    entity.MaintenanceCost = value;
                }
            }

            if (headers[Race].HasValue)
            {
                entity.Race = races
                    .Where(
                        e =>
                        e.Name.Equals(data[index + headers[Race].Value],
                                      StringComparison.InvariantCultureIgnoreCase))
                    .FirstOrDefault();
            }

            if (headers[Province].HasValue)
            {
                int value;
                if (int.TryParse(data[index + headers[Province].Value], out value))
                {
                    entity.ProvinceRequeriment = value;
                }
            }

            if (headers[Law].HasValue)
            {
                int value;
                if (int.TryParse(data[index + headers[Law].Value], out value))
                {
                    entity.LawRequeriment = value;
                }
            }

            if (headers[Temple].HasValue)
            {
                int value;
                if (int.TryParse(data[index + headers[Temple].Value], out value))
                {
                    entity.TempleRequeriment = value;
                }
            }

            if (headers[Guild].HasValue)
            {
                int value;
                if (int.TryParse(data[index + headers[Guild].Value], out value))
                {
                    entity.GuildRequeriment = value;
                }
            }

            if (headers[ResearchedBy].HasValue)
            {
                entity.Designer = domains
                    .Where(
                        e =>
                        e.Name.Equals(data[index + headers[ResearchedBy].Value],
                                      StringComparison.InvariantCultureIgnoreCase))
                    .FirstOrDefault();
            }

            if (headers[PublicInformation].HasValue)
            {
                entity.PublicInformation = data[index + headers[PublicInformation].Value];
            }

            if (headers[OwnerInformation].HasValue)
            {
                entity.OwnerInformation = data[index + headers[OwnerInformation].Value];
            }

            if (headers[GMInformation].HasValue)
            {
                entity.GMInformation = data[index + headers[GMInformation].Value];
            }
        }
    }
}
